#!/usr/bin/python3

import pandas as pd
import numpy as np
from pathlib import Path
import os

T = 8928 # time
M = 35 # client
N = 135 # n site
Q = 400 # QOS constraint

output = "fake_data"

client_name = []
site_name = []

def gen_id():
    import string
    from itertools import product

    client_name_pool = [a[0] + a[1] for a in product(string.ascii_uppercase, string.digits)] + list(string.ascii_uppercase)
    site_name_pool = [a[0] + a[1] for a in product(string.ascii_lowercase, string.digits)] + list(string.ascii_lowercase)
    
    
    client = np.random.choice(client_name_pool, M, replace=False).tolist()
    site = np.random.choice(site_name_pool, N, replace=False).tolist()
    
    return client, site

def gen_demand():
    MAX_DEMAND = 550000
    
    mean_mean, mean_std = 7650.0, 5549.0
    std_mean, std_std = 5921.0, 4665.0

    means = np.random.normal(mean_mean, mean_std / 2.5, size=M)
    while (means < 0).any():
        means = np.random.normal(mean_mean, mean_std / 2.5, size=M)
    
    stds = np.random.normal(std_mean, std_std / 2.5, size=M)
    while (stds < 0).any():
        stds = np.random.normal(std_mean, std_std / 2.5, size=M)

    d = np.random.multivariate_normal(means, np.diag(stds), size=T).astype(int)
    while (d < 0).any():
        d = np.random.multivariate_normal(means, np.diag(stds), size=T).astype(int)

    d[d < 0] = 0
    d[d > MAX_DEMAND] = MAX_DEMAND

    # d = np.random.randint(0, MAX_DEMAND, (T, M))
    
    demands = pd.DataFrame(d, columns=client_name)
    
    demands.insert(0, column='mtime', value=pd.to_datetime(pd.Timestamp('2022-03-22T00:00') + pd.timedelta_range(start='0 minute', periods=T ,freq='300S')).strftime('%Y-%m-%dT%H:%M'))
    
    return demands

def gen_bandwidth():
    MAX_BANDWIDTH = 1000000
    
    bandwidth = np.random.randint(430080 - 10, 430080 + 10, size=(N, 1))
    
    site_bandwidth = pd.DataFrame(bandwidth, columns=['bandwidth'])
    
    site_bandwidth.insert(0, column='site name', value=site_name)
    
    return site_bandwidth

def gen_qos():
    MAX_QOS = 1000
    
    ave = np.random.normal(0.3, 0.1, size=M)

    while (ave < 0).any():
        ave = np.random.normal(0.3, 0.1, size=M)

    q = np.array([np.random.binomial(1, p, size=N) for p in ave]).transpose() * 100 + 350

    # q = np.random.poisson(Q - 1, size=(N, M)) + 1
    
    qos = pd.DataFrame(q, columns=client_name)
    
    qos.insert(0, column='site name', value=site_name)
    
    return qos

if __name__=='__main__':
    client_name, site_name = gen_id()
    
    os.makedirs(output, exist_ok=True)
    
    base_dir = Path(output)
    
    demand = gen_demand()
    demand.to_csv(base_dir.joinpath('demand.csv'), index=False)
    
    site_bandwidth = gen_bandwidth()
    site_bandwidth.to_csv(base_dir.joinpath('site_bandwidth.csv'), index=False)
    
    qos = gen_qos()
    qos.to_csv(base_dir.joinpath('qos.csv'), index=False)
    
    with base_dir.joinpath('config.ini').open('w') as f:
        f.write('[config]\n')
        f.write(f'qos_constraint={Q}')